import { GetGL } from "./gl";

// 顶点着色器代码
var VSHADER_SOURCE = `
    attribute vec4 posuv;
    uniform vec2 size;
    varying vec2 uv;

    void main() {
        vec4 pos = vec4(posuv.xy,0.,1.);
        vec4 pos1  =vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,0.,1.0);
        gl_Position=pos1;
        // gl_Position = vec4(vec2(posuv), 0., 1.);
        uv = posuv.zw;
    }
`;

// 片元着色器代码
var FSHADER_SOURCE = `
    precision mediump float;
    varying vec2 uv;
    uniform sampler2D texture; 

    void main() {
        vec4 color = texture2D(texture, uv);
    }
`;

export const ShaderValueType = {
    Texture: 1,

    Vec2: 2,

    Float: 3,
};
export class Shader {
    vs = VSHADER_SOURCE;
    ps = FSHADER_SOURCE;
    _values = {};
    constructor(vs, ps) {
        vs && (this.vs = vs);
        ps && (this.ps = ps);
    }

    setValue(name, value) {
        this._values[name] = value;
    }

    setAttributes(attributes) {
        this._attributes = attributes;
        this.verticesNum = 0;
        for (let i = 0; i < attributes.length; i++) {
            this.verticesNum += attributes[i][1];
        }
    }

    bind(vertices) {
        let gl = GetGL();
        if (!this._program) {
            this._program = createProgram(gl, this.vs, this.ps);
        }
        gl.useProgram(this._program);
        for (let name in this._values) {
            this._bindValue(name, this._values[name]);
        }

        let data = new Float32Array(vertices);

        // 创建顶点缓冲区
        let vertexTexCoordBuffer = gl.createBuffer();

        // 绑定缓冲区
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

        // 获取数组每个元素的大小
        let FSIZE = data.BYTES_PER_ELEMENT;

        let stride = 0;
        for (let i = 0; i < this._attributes.length; i++) {
            stride += this._attributes[i][1] * 4;
        }
        let startIdx = 0;
        for (let i = 0; i < this._attributes.length; i++) {
            let attribute = this._attributes[i];
            // 获取 attribute 的存储位置并设置缓冲区
            var loc = gl.getAttribLocation(this._program, attribute[0]);
            gl.vertexAttribPointer(loc, attribute[1], attribute[2], false, stride, startIdx);
            gl.enableVertexAttribArray(loc);
            startIdx += attribute[1] * 4;
        }

    }

    _bindValue(name, value) {
        let gl = GetGL();
        if (value.type == ShaderValueType.Texture) {
            let texture = gl.createTexture();
            let loc = gl.getUniformLocation(this._program, name);
            loadTexture(gl, texture, loc, value.value, value.index);
        } else if (value.type == ShaderValueType.Vec2) {
            let loc = gl.getUniformLocation(this._program, name);
            gl.uniform2fv(loc, value.value);
        } else if (value.type == ShaderValueType.Float) {
            let loc = gl.getUniformLocation(this._program, name);
            gl.uniform1f(loc, value.value);
        }
    }
}


// 加载材质
function loadTexture(gl, texture, u_Sampler, image, index) {
    // if (index == 0)
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    gl.activeTexture(gl['TEXTURE' + index]);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.uniform1i(u_Sampler, index);
    return true;
}